package examstarter;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
import java.sql.SQLException;
import java.util.ArrayList;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import rmi.Login;
import rmi_impl.LoginClass;
import structure.Course;
import structure.Exam;
import structure.Student;
import stuff.DisposeAction;

import gui.GUIHome;
import gui.GUIMain;

public class GUIStarter extends GUIMain{
	
	private static final long serialVersionUID = 1L;
	private GUIStarterLeft left;
	private GUIStarterRight right;
	private LoginClass login;
	private Login stub;
	private GUIHome regExporter;
	private String ipString;
	private int port;
	
	public GUIStarter(JFrame cur, JFrame ex, GUIHome exGUI, int cornerIndex) {
		super(cur, cornerIndex);
		this.regExporter = exGUI;
		this.setTitle("TIẾN HÀNH THI");
		this.exitButton.setAction(new CustomDisposeAction(cur,ex, exGUI));
		
		left = new GUIStarterLeft(this);
		left.setMaximumSize(new Dimension(400, 700));
		right = new GUIStarterRight(this);
		
		this.bottomPanel.setLayout(new BorderLayout());
		this.bottomPanel.setOpaque(false);
		this.bottomPanel.setBorder(new EmptyBorder(0, 10, 10, 10));
		
		JPanel panel = new JPanel();
		panel.setOpaque(false);
		panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
		panel.add(left);
		panel.add(right);
		this.bottomPanel.add(panel,BorderLayout.CENTER);
	}
	
	public GUIStarterRight getRightPanel(){
		return this.right;
	}
	
	public GUIStarterLeft getLeftPanel(){
		return this.left;
	}
	
	public void startACourse(Course course, Exam exam){
		login.addNewCourse(course, exam);
	}
	
	public void removeACourse(final int courseId, final int numofquestion){
		login.removeCourse(courseId);
		
		new Thread(){

			@Override
			public void run() {
				markingaCourse(courseId, numofquestion);	
			}
		}.start();
	}
	
	private void markingaCourse(int courseId, int numofquestion){
		try {
			ArrayList<Student> arrayStudent = GUIMain.getDb().getStudentsByCourse(courseId);
			for(Student count : arrayStudent){
				if(GUIMain.getDb().getMarkofStudent(count.getiD()) == -1){
					if(login.requestMarking(count.getiD())){
					}else{
						GUIMain.getDb().UpdateStudent(count.getiD(), count.getMSTS(), count.getFirstName(), count.getLastName(),
								count.getDateOfBirth(), count.getCMND(), count.getJoinedCourse(),
								0, count.getUsername(), count.getPassword());
					}
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	public boolean startServer(){
		File ipFile = new File("portConfig.dbz");
		if(ipFile.exists()){
			try {
				DataInputStream is = new DataInputStream(new FileInputStream(ipFile));
				port = is.readInt();
				is.close();
			} catch (IOException e) {
				port = 27000;
			}
		}
		else{
			port = 27000;
		}
		try {
			InetAddress ip = InetAddress.getLocalHost();
			ipString = ip.getHostAddress();
			System.setProperty("java.rmi.server.hostname", ip.getHostAddress());
		} catch (UnknownHostException e1) {
			e1.printStackTrace();
			JOptionPane.showMessageDialog(this, "Không lấy được địa chỉ IP của máy chủ.",
					"Thông báo", JOptionPane.ERROR_MESSAGE);
			return false;
		};
		try {
			if(regExporter.getRegistry() == null){
				regExporter.setRegistry(LocateRegistry.createRegistry(port));
			}
		} catch (RemoteException e) {
			e.printStackTrace();
			JOptionPane.showMessageDialog(this, "Đã có một máy chủ khác hoặc một chương trình nào đó sử dụng port " + port,
					"Thông báo", JOptionPane.ERROR_MESSAGE);
			return false;
		}
		
		if(login == null){
			try {
				login = new LoginClass();
			} catch (RemoteException e) {
				e.printStackTrace();
				return false;
			}
		}
		
		try {
			stub = (Login)UnicastRemoteObject.exportObject(login,0);
		} catch (RemoteException e) {
			e.printStackTrace();
			return false;
		}
		
		try {
			regExporter.getRegistry().rebind("Login", stub);
		} catch (RemoteException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
	
	public boolean stopServer(){
		if(login == null) return false;
		if(!login.cancelable()){
			return false;
		}
		if(regExporter.getRegistry() == null) return false;
		try {
			regExporter.getRegistry().unbind("Login");
			UnicastRemoteObject.unexportObject(login, true);
			login.clear();
			login = null;
			right.clear();
			return true;
		} catch (RemoteException | java.rmi.NotBoundException e) {
			e.printStackTrace();
			return false;
		}
	}
	
	public String getIp(){
		return this.ipString;
	}
	
	public int getPort(){
		return this.port;
	}
	
	class CustomDisposeAction extends DisposeAction{

		public CustomDisposeAction(JFrame cur, JFrame ex, GUIMain exGUI) {
			super(cur, ex, exGUI);
		}

		@Override
		public void actionPerformed(ActionEvent e) {
			stopServer();
			super.actionPerformed(e);
		}

		private static final long serialVersionUID = 1L;
		
	}
}
